package com.audaque.springboot.foshanupload.agent;

import com.audaque.springboot.foshanupload.agent.transformer.MyTransformer;
import org.apache.commons.lang3.StringUtils;

import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.util.Arrays;
import java.util.Objects;

public class MyAgent {
    public static String handle(String agentArgs, Instrumentation inst) {
        System.out.println("agent参数:" + agentArgs);
        String[] splits = agentArgs.split(",");
        String classNameKeyValue = Arrays.stream(splits).filter(e -> Objects.equals(e.split("=")[0], "handleClassName")).findAny().orElse(null);
        String handleClassName = "";
        if (StringUtils.isNotBlank(classNameKeyValue)) {
            String[] split = classNameKeyValue.split("=");
            handleClassName = split[1];
        }
        if (StringUtils.isNotBlank(handleClassName)) {
            inst.addTransformer(new MyTransformer(handleClassName), true);
        }
        Class[] classes = inst.getAllLoadedClasses();
        for (Class cls : classes) {
            System.out.println(cls.getName());
        }
        return handleClassName;
    }

    /**
     * jvm 参数形式启动，运行此方法
     *
     * @param agentArgs
     * @param inst
     */
    public static void premain(String agentArgs, Instrumentation inst) {
        handle(agentArgs, inst);
    }

    /**
     * 动态 attach 方式启动，运行此方法
     *
     * @param agentArgs
     * @param inst
     */
    public static void agentmain(String agentArgs, Instrumentation inst) {
        String handleClassName = handle(agentArgs, inst);
        if (StringUtils.isNotBlank(handleClassName)) {
            Class[] allClass = inst.getAllLoadedClasses();
            System.out.println("类加载:" + allClass.length);
            int count=0;
            for (Class c : allClass) {
                String name = c.getName();
                System.out.println("类已加载:" + count++);
                if (name.contains(handleClassName)) {
                    try {
                        //agentmain 是JVM运行时，需要调用 retransformClasses 重定义类 ！！
                        inst.retransformClasses(c);
                    } catch (UnmodifiableClassException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            System.out.println("类加载结束" );
        }
    }
}

